import React, { useState, useEffect, useCallback, useRef } from "react";
import { useNavigate } from "react-router-dom";
import { Button, Table, Space, Form, Input, Popconfirm, DatePicker, Select } from "antd";
import {
  DeleteOutlined,
  SearchOutlined,
  SyncOutlined,
  DownOutlined,
  EyeOutlined,
  EditOutlined,
  DownloadOutlined,
  ExportOutlined,
  UploadOutlined,
  ReloadOutlined,
} from "@ant-design/icons";
import TableLayout, {
  SearchContainer,
  SearchAction,
  SearchForm,
  OperateContainer,
  MainContainer,
} from "@/components/templates/TableLayout";
import { ButtonCollapsed, ModalComponent } from "@/components/iteration";

import { AuthButton } from "@/components/auth";

import dayjs from "dayjs";
import { saveAs } from "file-saver";
import {
  getTableList,
  getDbTableList,
  deleteTable,
  deleteBatchTable,
  importTable,
  downloadTable,
} from "@/api/tool/generate";
import PropTypes from "prop-types";

const AUTH_PERMISSION = {
  IMPORT: "tool:generate:import",
  DELETE: "tool:generate:delete",
  PREVIEW: "tool:generate:preview",
  CONFIG: "tool:generate:config",
  BUILD: "tool:generate:build",
};

/**
 * 导入信息对话框
 *
 * @param {Function} 回调函数
 * @returns {React.Component} Component
 */
const ImportModelComponent = ({ callback, children }) => {
  const [dataSource, setDataSource] = useState([]);
  const [selectedRowKeys, setSelectedRowKeys] = useState([]);
  const [open, setOpen] = useState(false);

  useEffect(() => {
    open &&
      getDbTableList().then((res) => {
        res.map((item) => (item.key = item.tableName));
        setDataSource(res);
      });
  }, [open]);

  const columns = [
    { key: "tableName", title: "表名称", dataIndex: "tableName" },
    { key: "tableComment", title: "表描述", dataIndex: "tableComment" },
    { key: "createTime", title: "创建时间", dataIndex: "createTime" },
    { key: "updateTime", title: "更新时间", dataIndex: "updateTime" },
  ];

  const onModalOK = async () => {
    if (!selectedRowKeys.length) return;
    await importTable(selectedRowKeys);
    setOpen(false);
    callback && callback(selectedRowKeys);
  };

  const onModalCancel = () => {
    setOpen(false);
  };

  return (
    <ModalComponent
      className="table-modal"
      open={open}
      title="导入"
      onOk={onModalOK}
      onCancel={onModalCancel}
      button={children}
      onButtonClick={() => setOpen(true)}
      destroyOnClose
    >
      <div className="general-wrpper">
        <div className="header-card"></div>
        <div className="table-card">
          <Table
            size="middle"
            columns={columns}
            dataSource={dataSource}
            rowSelection={{
              setSelectedRowKeys,
              onChange: (selectedKeys) => setSelectedRowKeys(selectedKeys),
            }}
          />
        </div>
      </div>
    </ModalComponent>
  );
};
ImportModelComponent.propTypes = {
  callback: PropTypes.func,
  children: PropTypes.node,
};

const HeaderComponent = ({ onSearch }) => {
  const [folded, setFolded] = useState(false);
  const [searchType, setSearchType] = useState("keyword");
  const inputRef = useRef(null);

  const onFinish = (values) => {
    const data = Object.entries(values).filter(([_, value]) => !!value);
    data.length && onSearch(Object.fromEntries(data));
  };

  const hanldeSearch = () => {
    const value = inputRef.current.input.value;
    value && onSearch({ [searchType]: value });
  };

  const options = [
    { label: "综合搜索", value: "keyword", placeholder: "综合搜索" },
    { label: "表名称", value: "tableName", placeholder: "请输入表名称" },
  ];

  return (
    <SearchContainer>
      <SearchAction>
        <Space.Compact>
          <Select
            defaultValue={searchType}
            style={{ width: 120 }}
            options={options}
            onChange={(v) => setSearchType(v)}
          />
          <Input ref={inputRef} placeholder={options.find((item) => item.value === searchType).placeholder} />
          <Button icon={<SearchOutlined />} onClick={hanldeSearch} />
        </Space.Compact>

        <ButtonCollapsed
          type="link"
          icon={<DownOutlined />}
          iconPosition="end"
          collapsed={folded}
          onClick={() => setFolded(!folded)}
        >
          高级搜索
        </ButtonCollapsed>
      </SearchAction>

      <SearchForm collapse={folded}>
        <Form layout="inline" autoComplete="off" onFinish={onFinish} onReset={() => onSearch()}>
          <Form.Item name="tableName" label="表名称">
            <Input placeholder="请输入表名称" />
          </Form.Item>

          <Form.Item name="createTimes" label="创建时间">
            <DatePicker.RangePicker format="YYYY/MM/DD" />
          </Form.Item>

          <Form.Item>
            <Space>
              <Button type="primary" icon={<SearchOutlined />} htmlType="submit">
                搜索
              </Button>
              <Button icon={<SyncOutlined />} htmlType="reset">
                重置
              </Button>
            </Space>
          </Form.Item>
        </Form>
      </SearchForm>
    </SearchContainer>
  );
};
HeaderComponent.propTypes = {
  onSearch: PropTypes.func,
  onReset: PropTypes.func,
};

const OperateCompoent = ({ importCallBack, onBatchDelete, isDeleteDisabled, onRefresh }) => {
  const navigate = useNavigate();
  return (
    <OperateContainer>
      <Space>
        <ImportModelComponent callback={importCallBack}>
          <AuthButton auth={AUTH_PERMISSION.IMPORT} type="primary" ghost icon={<UploadOutlined />}>
            导入
          </AuthButton>
        </ImportModelComponent>
        <Popconfirm
          title="系统提示"
          description="是否确认删除多项用户的数据项？"
          onConfirm={() => onBatchDelete}
          okText="是"
          cancelText="否"
        >
          <AuthButton auth={AUTH_PERMISSION.DELETE} danger ghost icon={<DeleteOutlined />} disabled={isDeleteDisabled}>
            删除
          </AuthButton>
        </Popconfirm>
      </Space>
      <Space>
        <Button icon={<ReloadOutlined />} onClick={onRefresh} />
        <AuthButton auth={AUTH_PERMISSION.EXPORT} icon={<ExportOutlined />} onClick={() => navigate("export")} />
      </Space>
    </OperateContainer>
  );
};
OperateCompoent.propTypes = {
  importCallBack: PropTypes.func,
  isDeleteDisabled: PropTypes.bool,
  onBatchDelete: PropTypes.func,
  onRefresh: PropTypes.func,
};

const GeneralComponent = () => {
  const navigate = useNavigate();
  const [loading, setLoading] = useState(false);
  const [dataSource, setDataSource] = useState([]);
  const [selectedRowKeys, setSelectedRowKeys] = useState([]);

  const onGetData = useCallback((options = {}) => {
    setLoading(true);
    getTableList(options)
      .then((res) => setDataSource(res))
      .finally(() => setLoading(false));
  }, []);

  // 初始化数据
  useEffect(() => onGetData(), [onGetData]);

  const onSearch = (values) => {
    if (values?.createTimes) {
      let [startCreateTime, endCreateTime] = values.createTimes;
      startCreateTime = dayjs(startCreateTime).format("YYYY-MM-DD");
      endCreateTime = dayjs(endCreateTime).format("YYYY-MM-DD");
      values.params = { startCreateTime, endCreateTime };
      Reflect.deleteProperty(values, "createTimes");
    }
    if (values?.updateTimes) {
      let [startUpdateTime, endUpdateTime] = values.createTimes;
      startUpdateTime = dayjs(startUpdateTime).format("YYYY-MM-DD");
      endUpdateTime = dayjs(endUpdateTime).format("YYYY-MM-DD");
      values.params = { startUpdateTime, endUpdateTime };
      Reflect.deleteProperty(values, "updateTimes");
    }
    onGetData(values);
  };

  const onDelete = async (value) => {
    await deleteTable(value);
    onGetData();
  };

  const onBatchDelete = async () => {
    if (!selectedRowKeys.length) return;
    await deleteBatchTable(selectedRowKeys);
    onGetData();
  };

  const onDownloadCode = async (value) => {
    const res = await downloadTable(value.tableId);
    saveAs(res, `randi-${value.tableName}.zip`);
  };

  const columns = [
    { key: "tableName", title: "表名称", dataIndex: "tableName" },
    { key: "tableComment", title: "表描述", dataIndex: "tableComment" },
    { key: "createTime", title: "创建时间", dataIndex: "createTime" },
    {
      title: "Action",
      key: "action",
      render: (_, record) => (
        <Space>
          <AuthButton
            auth={AUTH_PERMISSION.PREVIEW}
            type="link primary"
            ghost
            icon={<EyeOutlined />}
            onClick={() => navigate(`preview/${record.key}`)}
          >
            预览
          </AuthButton>

          <AuthButton
            auth={AUTH_PERMISSION.CONFIG}
            type="link success"
            ghost
            icon={<EditOutlined />}
            onClick={() => navigate(`config/${record.key}`)}
          >
            配置
          </AuthButton>

          <AuthButton
            auth={AUTH_PERMISSION.BUILD}
            type="link warning"
            icon={<DownloadOutlined />}
            onClick={() => onDownloadCode(record)}
          >
            生成
          </AuthButton>

          <Popconfirm
            title="系统提示"
            description={`是否确认删除数据项？`}
            onConfirm={() => onDelete(record.key)}
            okText="是"
            cancelText="否"
          >
            <AuthButton auth={AUTH_PERMISSION.DELETE} type="link" danger icon={<DeleteOutlined />}>
              删除
            </AuthButton>
          </Popconfirm>
        </Space>
      ),
    },
  ];

  return (
    <TableLayout>
      <HeaderComponent onSearch={onSearch} />
      <OperateCompoent
        importCallBack={() => onGetData()}
        isDeleteDisabled={!selectedRowKeys.length}
        onBatchDelete={onBatchDelete}
        onRefresh={() => onGetData()}
      />

      <MainContainer>
        <Table
          size="middle"
          loading={loading}
          columns={columns}
          dataSource={dataSource}
          pagination={false}
          rowSelection={{
            selectedRowKeys,
            onChange: (selectedKeys) => setSelectedRowKeys(selectedKeys),
          }}
        />
      </MainContainer>
    </TableLayout>
  );
};

export default GeneralComponent;
